import React from "react";

class App extends React.Component {
  // constructor(props) {
  //   super(props); // 构造函数第一步，必须是调用 super()

  //   // 构造函数初始化 state
  //   this.state = {
  //     name: "张三",
  //     age: 18,
  //   };
  // }

  // 直接初始化 state (public class fileds 语法)
  state = {
    name: "张三",
    age: 18,
    count: 1,
  };

  render() {
    console.log("this", this);
    const { name, age } = this.state;
    return (
      <div>
        <h1>App</h1>
        <p>
          姓名：{this.state.name} - {name}
        </p>
        <p>
          年龄：{this.state.age} - {age}
        </p>
        <hr />
        <button
          onClick={() => {
            // 箭头函数形式的事件处理函数
            console.log("onClick", this.state.name);
            // 错误的直接修改state数据
            // this.state.name = "李四";
            // 正确的使用setState函数来修改数据
            this.setState({
              name: "李四",
            });
          }}
        >
          点我，修改 name 为李四
        </button>
        <button
          onClick={() => {
            this.setState({
              // 这里不要使用 this.state.age++ 会修改原数据
              age: this.state.age + 1,
            });
          }}
        >
          age++
        </button>

        {/* 演示：多次setState会合并成一次的现象 */}
        <button
          onClick={() => {
            // 期望 count 会加 5次，最后得到 6, 但是现象是只加了一次
            // for (let i = 1; i <= 5; i++) {
            //   this.setState({
            //     count: this.state.count + 1,
            //   });
            // }
            // 可以通过给 setState 传递函数的方式来解决上面这个现象
            for (let i = 1; i <= 5; i++) {
              this.setState((prevState) => {
                // prevState 是上一次 setState 之后的 state 数据，它是新的。
                return {
                  count: prevState.count + 1,
                };
              });
            }
            // 总结：setState 时，如果需要依赖现有数据的话，最好使用函数的写法+prevState参数的方式
          }}
        >
          {this.state.count}
        </button>

        {/* 演示：setState是异步的现象 */}
        <button
          onClick={() => {
            // this.setState({
            //   name: "李四",
            // });
            // console.log("this.state.name", this.state.name); // '张三'

            // 要拿到最新的数据或真实DOM，可以给 setState 传递第二个参数，该参数是个回调函数, 在这个回调函数中获取
            this.setState(
              {
                name: "李四",
              },
              () => {
                // 该回调函数的执行时机，是等这次数据更新引起组件重新render且真实DOM数据更新之后，触发
                // 类似 Vue 中 nextTick 的玩法。
                console.log("this.state.name", this.state.name); // '李四'
              }
            );
          }}
        >
          {this.state.name}
        </button>
      </div>
    );
  }
}

export default App;
